<template>
  <el-card class="def-page" v-if="options?.length">
    <!-- 表单查询 S -->
    <template v-if="isShowQueryForm">
      <def-form
        v-bind="queryFormAttrs"
        :formOptions="queryFormOptions"
        @search="onSearch"></def-form>
    </template>
    <!-- 表单查询 E -->

    <!-- 对话框表单 S -->
    <def-dialog-form
      ref="dialogFormRef"
      :dialog="dialogAttrs"
      :form="dialogFormAttrs"
      :list="dialogFormOptions"
      :data="dialogFormData"
      :type="dialogType"
      @confirm="onConfirm">
    </def-dialog-form>
    <!-- 对话框表单 E -->

    <!-- 表格列表 S -->
    <def-table
      v-bind="tableAttrs"
      :list="options"
      :data="data"
      @rowAdd="onRowAdd"
      @rowEdit="onRowEdit"
      @rowDelete="onRowDelete">
      <template v-for="item in options" :key="item.prop" #[item.prop]="scope">
        <slot :name="scope.prop" :row="scope.row" :$index="scope.$index"></slot>
      </template>
    </def-table>
    <!-- 表单列表 E -->

    <!-- 分页查询 S -->
    <def-pagination
      v-if="pagination"
      ref="paginationRef"
      v-model:currentPage="paginationCurrent"
      v-model:pageSize="paginationSize"
      :total="paginationTotal"
      v-bind="attrs?.pagination"></def-pagination>
    <!-- 分页查询 E -->
  </el-card>
</template>

<script lang="ts" setup>
import { PropType, provide, reactive, ref, watch, watchEffect } from 'vue'
import { IFormItem } from '@/base-ui/form/types'
import { IElTable } from '@/base-ui/table/types'

type TTableFormAction = 'add' | 'edit'

const props = defineProps({
  // 页面配置
  options: {
    type: Array,
    required: true
  },
  // 表格数据
  data: {
    type: Array,
    default: () => []
  },
  // 组件属性
  attrs: {
    type: Object as PropType<any>,
    default: () => ({
      // 查询表单属性
      queryForm: {},
      // 对话框属性
      dialog: {},
      // 对话框表单属性
      dialogForm: {},
      // 表格属性
      table: {},
      // 分页属性
      pagination: {}
    })
  },
  // 是否显示分页
  pagination: {
    type: Boolean,
    default: true
  },
  // 当前页码
  currentPage: {
    type: Number,
    default: 1
  },
  // 每页条数
  pageSize: {
    type: Number,
    default: 10
  },
  // 总条数
  total: {
    type: Number,
    default: 0
  }
})

const emits = defineEmits<{
  (e: 'get', model: any, close: () => void): void
  (e: 'add', model: any, get: () => void): void
  (e: 'edit', model: any, get: () => void): void
  (e: 'del', model: any, get: () => void): void
}>()

const paginationRef = ref()

/* 表单查询 S */
// 是否显示查询表单
const isShowQueryForm = ref<boolean>(true)
// 查询表单属性
const queryFormAttrs = reactive({
  layout: {
    gutter: 50,
    xs: 24,
    sm: 24,
    md: 12,
    lg: 8,
    xl: 6
  },
  ...props.attrs.queryForm
})
// 查询表单项配置
const queryFormOptions = ref<IFormItem[]>([])
// 查询
const queryFormModel: any = ref({})
const onSearch = (model: any) => {
  console.log('表单查询', model)
  if (model) {
    const tempModel: any = {}
    Object.keys(model).forEach((modelKey: any) => {
      if (!model[modelKey]) return
      tempModel[modelKey] = model[modelKey]
    })
    queryFormModel.value = tempModel
  }
  getList()
}
/* 表单查询 E */

/* 对话框表单 S */
// 对话框实例
const dialogFormRef = ref()
// 对话框属性
const dialogAttrs = reactive({ ...props.attrs.dialog })
// 对话框表单配置
const dialogFormAttrs = reactive({ ...props.attrs.dialogForm })
// 对话框表单项配置
const dialogFormOptions = ref<IFormItem[]>([])
// 对话框表单数据回显
const dialogFormData = ref<any>(null)
// 对话框表单按钮确定
const onConfirm = (model: any) => {
  console.log('onDialogConfirm', model)
  if (dialogType.value === 'add') {
    console.log('表单新增确认')
    emits('add', model, getList)
  } else if (dialogType.value === 'edit') {
    console.log('表单修改确认')
    emits('edit', model, getList)
  }
}
/* 对话框表单 E */

/* 表格查询 S */
const dialogType = ref<TTableFormAction>('add')
// 表格属性
const tableAttrs = reactive<IElTable>({ ...props.attrs.table })
// 表格事件处理
const onRowAdd = () => {
  console.log('onRowAdd')
  dialogType.value = 'add'
  // dialogAttrs.title = '表单新增'
  dialogFormData.value = null
  dialogFormRef.value?.open()
}
const onRowEdit = (row: any) => {
  console.log('onRowEdit', row)
  dialogType.value = 'edit'
  // dialogAttrs.title = '表单编辑'
  dialogFormData.value = row
  dialogFormRef.value?.open()
}
const onRowDelete = (row: any) => {
  console.log('onRowDelete', row)
  emits('del', row, getList)
}
/* 表格查询 E */

/* 分页查询 S */
const paginationCurrent = ref<number>(props.currentPage)
const paginationSize = ref<number>(props.pageSize)
const paginationTotal = ref<number>(props.total)
// 表格 loading 状态
const isLoading = ref(false)
const close = () => {
  isLoading.value = false
}
provide('isLoading', isLoading)

const resetCurrentPage = () => {
  paginationRef.value?.initCurrentPage()
}
provide('resetCurrentPage', resetCurrentPage)

const getList = (page = paginationCurrent.value, pageSize = paginationSize.value) => {
  isLoading.value = true
  try {
    emits(
      'get',
      {
        page,
        pageSize,
        ...queryFormModel.value
      },
      close
    )
  } catch {
    close()
  }
}
props.pagination && getList()
provide('getList', getList)

/* watch(
  paginationCurrent,
  (value, oldValue) => {
    if (value !== oldValue) { getList(value, paginationSize.value) }
  }
)
watch(
  paginationSize,
  (value, oldValue) => {
    if (value !== oldValue) { getList(paginationCurrent.value, value) }
  }
) */

watch(
  () => props.total,
  (value) => {
    paginationTotal.value = value
  }
)
/* 分页查询 E */

// 初始化对话框表单项配置
const initDialogForm = () => {
  dialogFormOptions.value = props.options?.map(({ label, prop, formItem }: any) => {
    return {
      label,
      prop,
      ...formItem
    }
  })
}
// 初始化查询表单项配置
const initQueryForm = () => {
  queryFormOptions.value = props.options
    .filter((item: any) => item?.formItem?.query)
    .map(({ label, prop, formItem, queryFormItem }: any) => {
      // 删除表单校验
      formItem.rules && delete formItem.rules
      return {
        label,
        prop,
        ...formItem,
        ...queryFormItem
      }
    })
  isShowQueryForm.value = queryFormOptions.value.length > 0
}

// 初始化页面配置
const initOptions = () => {
  if (!props.options?.length) throw new Error('缺乏页面配置')
  // 初始化表单项配置
  initDialogForm()
  initQueryForm()
}
initOptions()
</script>

<style scoped lang="scss">
.def-page {
  height: 100%;
  :deep(.el-card__body) {
    height: inherit;
    @include flexCol;
    box-sizing: border-box;
    .def-table {
      flex: 1;
    }
  }
}
</style>
